#include <bits/stdc++.h>
#define int long long 
using namespace std;

const int maxn = 2e5 + 10;
// color 存对应每种颜色的个数
// num 存储 颜色个数为 i 的有几个
// 比如 num[x][i]=5, 说明 x 这个子树中有 5 种颜色的个数为 i
// 判断平衡, 那么所有的 颜色的个数应该都相同, 此时 num[x].size ==1
map<int, int> color[maxn], num[maxn]; 
vector<int> adj[maxn]; 
int n;
int ans;

void dfs(int u){
	for(auto nex: adj[u]){
		dfs(nex);
		// 树上启发式合并
		if(color[u].size()<color[nex].size()){ // 保证 u 是大的那个
			color[u].swap(color[nex]);
			num[u].swap(num[nex]);
		}
		// 开始合并
		for(auto it=color[nex].begin();it!=color[nex].end();it++){
			// C ++ 11 不能使用 auto[]
			int c1=it->first; // 颜色 
			int cnt=it->second; // 个数
			if(color[u].count(c1)){ // 之前有过这个颜色
				int c=color[u][c1];
				num[u][c]--; // 注意这里面是 --
				if(num[u][c]==0){ // 变成 0 个了
					num[u].erase(c); // 将0 个的删除, 这里一定不要忘了
				}
				color[u][c1]+=cnt;
			} else { // 之前没有这种颜色
				color[u][c1]+=cnt;
			}
			num[u][color[u][c1]]++;
		}
		
		// 合并之后释放空间
		map<int, int> tmp1, tmp2;
		color[nex].swap(tmp1);
		num[nex].swap(tmp2);
	}
	
	if(num[u].size()==1){
		ans++;
	}
}

void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int col,fa;
		cin>>col>>fa;
		adj[fa].push_back(i);
		color[i][col]++;
		num[i][1]++; // 这个子树中有颜色个数为 1 的有 1 个
	}
	dfs(1);
	
	cout<<ans <<'\n';
}

signed main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	solve();
	return 0;
}
